package model.alumnos;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;



import model.carrerasYPlanes.Carrera;
import model.carrerasYPlanes.PlanDeEstudio;
import model.materiasYCatedras.Catedra;
import model.materiasYCatedras.MateriaPorPlanDeEstudio;
import model.oficinaDeAlumnos.OficinaDeAlumnos;

public class AlumnoEnCarrera {
	private int legajo;
	private List<Catedra> catedrasInscripto = new ArrayList<Catedra>();
	private Alumno alumno;
	private EstadoDeAlumno estado;
	private int cantidadDeLicenciasPedidas;
	private PlanDeEstudio planDeEstudio;
	private Map<MateriaPorPlanDeEstudio, Double> materiasCursadas = new HashMap<MateriaPorPlanDeEstudio, Double>();
	

	//CONSTRUCTOR
	public AlumnoEnCarrera(Alumno alumno, PlanDeEstudio plan, int legajo){
		super();
		this.cantidadDeLicenciasPedidas = 0;
		this.alumno = alumno;
		this.planDeEstudio = plan;
		this.estado = new Regular(this);
		this.setLegajo(legajo);
	}
	
	public AlumnoEnCarrera(PlanDeEstudio plan){
		this.setPlanDeEstudio(plan);
	}
	
	public AlumnoEnCarrera(){
		
	}
	
	//--------------------------------------------------------------------------------


	/**
	 * Agrega una catedra a las catedras en las que se encuentra inscripto el alumno
	 * @param unaMateria
	 * @return
	 */
	
	public void agregarCatedrasInscripto(Catedra unaCatedra){
		this.getCatedrasInscripto().add(unaCatedra);
	}
	
	/**
	 * Le agrega una materia cursada al alumno en carrera con la nota correspondiente
	 *
	 */
	
	public void agregarMateriaCursada(MateriaPorPlanDeEstudio unaMateria, Double nota){
		this.getMateriasCursadas().put(unaMateria, nota);
	}
	
	/**
	 * Devuelve un boolean indicando si aprobo la materia por plan de estudio
	 * o no, o sea si la nota es mayor a 6
	 *
	 */
	
	public boolean tieneAprobada(MateriaPorPlanDeEstudio unaMateria){
		return (this.getMateriasCursadas().get(unaMateria) > 6);
	}
	
	/**
	 * Comprueba si el alumno es regular o no
	 *
	 */
	public boolean soyRegular(){
		return this.getEstado().isRegular();
	}
	
	/**
	 * Vuelve regular al alumno que era irregular
	 *
	 */
	public void regularizar(){
		this.getEstado().regularizar();
	}
	
	
	/**
	 * Otorga una licencia al alumno
	 *
	 */
	public void otorgarLicencia(){
		this.getEstado().otorgarLicencia();
	}
	
	/**
	 * Devuelve una lista con las materias en las cuales el alumno esta inscripto
	 *
	 */
	public List<MateriaPorPlanDeEstudio> materiasInscripto(){
		List<MateriaPorPlanDeEstudio> materiasInscripto = new ArrayList<MateriaPorPlanDeEstudio>();
		for(Catedra catedra : this.getCatedrasInscripto()){
			materiasInscripto.add(catedra.getMateria());
		}
		return materiasInscripto;
	}
	
	/**
	 * Este metodo comprueba si el alumno esta inscripto en la materia
	 * pasada por parametro o no
	 *
	 */
	public Boolean estaInscriptoEnMateria(MateriaPorPlanDeEstudio mat){
		for (Catedra catedra : this.getCatedrasInscripto()) {
			if(catedra.getMateria() == mat){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Comprueba que tenga aprobada todas las correlativas de la materia pasada por parametro
	 *
	 */
	public boolean tengoAprobadasTodasLasCorrelativas(MateriaPorPlanDeEstudio unaMateria){
		for(MateriaPorPlanDeEstudio materia : unaMateria.getCorrelativas()){
			if(!this.tieneAprobada(materia)){
				return false;
			}
		}
		return true;
	}

	/**
	 * Comprueba si la materia pasada por parametro es una materia del plan
	 * de estudio en el cual el alumno esta anotado
	 *
	 */
	public boolean esUnaMateriaDeMiPlanDeEstudio(MateriaPorPlanDeEstudio unaMateria){
		return this.getPlanDeEstudio().getMaterias().contains(unaMateria);
	}
	

	/**
	 * Devuelve el promedio total del alumno en carrera
	 *
	 */
	public Double promedio(){
		Double sumaDeNotas = 0.0;
		for(Double unaNota : this.getMateriasCursadas().values()){
			sumaDeNotas = sumaDeNotas + unaNota;
		}
		return sumaDeNotas/this.getMateriasCursadas().size();
	}
	
	
	/**
	 * Devuelve una lista de las materias que el alumno tiene aprobadas
	 *
	 */
	public List<MateriaPorPlanDeEstudio> getMateriasAprobadas(){
		List<MateriaPorPlanDeEstudio> materiasAprobadas = new ArrayList<MateriaPorPlanDeEstudio>();
		Iterator it = this.getMateriasCursadas().entrySet().iterator();
		while(it.hasNext()){
			Map.Entry e = (Map.Entry)it.next();
			if((Double)e.getValue() > 6){
				materiasAprobadas.add((MateriaPorPlanDeEstudio)e.getKey());
			}
		}
		return materiasAprobadas;
	}
	
	
	/**
	 * Devuelve los creditos obtenidos de todas las materias aprobadas hasta el momento
	 *
 	 */
	public int getCreditosObtenidos(){
		int creditos = 0;
		for(MateriaPorPlanDeEstudio unaMateria : this.getMateriasAprobadas()){
			creditos = creditos + unaMateria.getCreditos();
		}
		return creditos;
	}
	
	/**
	 * Devuelve los creditos que le restan para recibirse
	 *
	 */	
	public int creditosFaltantes(){
		return (this.getPlanDeEstudio().getCreditos() - this.getCreditosObtenidos());
	}
	
	
	/**
	 * Devuelve los creditos totales que tiene el plan de estudios en el cual
	 * el alumno esta inscripto
	 *
	 */
	public int getCreditosPlanDeEstudio(){
		return this.getPlanDeEstudio().getCreditos();
	}
	
	public Carrera getCarrera(){
		return this.planDeEstudio.getCarrera();
	}
	
	public String analitico(){
		StringBuffer str = new StringBuffer();
		Iterator it = this.getMateriasCursadas().entrySet().iterator();
		while(it.hasNext()){
			Map.Entry e = (Map.Entry)it.next();
			MateriaPorPlanDeEstudio mat = (MateriaPorPlanDeEstudio) e.getKey();
			Double nota = (Double) e.getValue();
			str.append("- " + mat);
			str.append("\n");
			str.append("-- ");
			str.append("Nota: " + nota);
			str.append("\n");
		}
		return str.toString();
	}
	
	
	/// Datos Personales
	
	public String getNombre(){
		return this.getAlumno().getNombre();
	}
	
	public String getApellido(){
		return this.getAlumno().getApellido();
	}
	
	public String getTelefono(){
		return this.getAlumno().getTelefono();
	}
	
	public String getSexo(){
		return this.getAlumno().getSexo();
	}
	
	public String getEstadoCivil(){
		return this.getAlumno().getEstadoCivil();
	}
	
	public String getCelular(){
		return this.getAlumno().getCelular();
	}
	
	public String getEMail(){
		return this.getAlumno().getEMail();
	}
	
	//Getters & Setters:
	
	
	public Alumno getAlumno() {
		return alumno;
	}


	public Map<MateriaPorPlanDeEstudio, Double> getMateriasCursadas() {
		return materiasCursadas;
	}

	public void setMateriasCursadas(
			Map<MateriaPorPlanDeEstudio, Double> materiasCursadas) {
		this.materiasCursadas = materiasCursadas;
	}

	public void setAlumno(Alumno alumno) {
		this.alumno = alumno;
	}

	public EstadoDeAlumno getEstado() {
		return estado;
	}
	
	
	public PlanDeEstudio getPlanDeEstudio() {
		return planDeEstudio;
	}

	public void setPlanDeEstudio(PlanDeEstudio planDeEstudio) {
		this.planDeEstudio = planDeEstudio;
	}

	public int getCantidadDeLicenciasPedidas() {
		return cantidadDeLicenciasPedidas;
	}

	public void setCantidadDeLicenciasPedidas(int cantidadDeLicenciasPedidas) {
		this.cantidadDeLicenciasPedidas = cantidadDeLicenciasPedidas;
	}

	public void setEstado(EstadoDeAlumno estado) {
		this.estado = estado;
	}

	public int getLegajo() {
		return legajo;
	}
	
	public void setLegajo(int legajo) {
		this.legajo = legajo;
	}
	public int getAusentes() {
		return this.getEstado().getAusentes();
	}
	public void setAusentes(int ausentes) {
		this.getEstado().setAusentes(ausentes);
	}
	public int getMateriasEnUltimoAnio() {
		return this.getEstado().getMateriasEnUltimoAnio();
	}
	public void setMateriasEnUltimoAnio(int materiasEnUltimoAnio) {
		this.getEstado().setMateriasEnUltimoAnio(materiasEnUltimoAnio);
	}

	public List<Catedra> getCatedrasInscripto() {
		return catedrasInscripto;
	}

	public void setCatedrasInscripto(List<Catedra> catedrasInscripto) {
		this.catedrasInscripto = catedrasInscripto;
	}

	
}
